#pragma once

#include <string>
#include "VarTable.h"
#include "Utilities.h"


VarTable::VarTable(void){
	nameTable = NameTableType();
	indexTable = IndexTableType(); 
	index=0;
}

VarTable::~VarTable(void){
	clear();
}

void VarTable::clear(){
	nameTable.clear();
	indexTable.clear(); 
	index = 0;
}

Type::Index::Var VarTable::insertVar(Type::Name::Var varName){
	// invalid variable name
	if(!Utilities::isValidVarName(varName)){
		return -1;
	} 

	// if variable name already exist in the table
	if(isVarExistsInVarTable(varName)){
		return getVarIndex(varName);
	}
	// variable does not exist, insert it into th table
	else{
		index++;
		nameTable.insert(std::make_pair<Type::Index::Var, Type::Name::Var>(index, varName));
		indexTable.insert(std::make_pair<Type::Name::Var, Type::Index::Var>(varName, index));
		return index;
	}
}

// get all variable indexes
const Type::List::Var& VarTable::getVarIndices(){
	Type::List::Var* varList = new Type::List::Var();
	for(NameTableType::iterator it=nameTable.begin(); it!=nameTable.end(); it++){
		varList->push_back(it -> first);
	}
	return *varList;
}

Type::Index::Var VarTable::getVarIndex(Type::Name::Var varName){
	// valid variable name length and variable exists
	if(Utilities::isValidVarName(varName) && isVarExistsInVarTable(varName)){
		return indexTable.at(varName);
	}else{
		return -1;
	}
}

Type::Name::Var VarTable::getVarName(Type::Index::Var varIndex){
	// valid variable index and variable exists
	if(Utilities::isValidVarIndex(varIndex) && isVarExistsInVarTable(varIndex)){
		return nameTable.at(varIndex);
	}else{
		return "";
	}
}

bool VarTable::isVarExistsInVarTable(Type::Name::Var varName){
	// valid variable name length and variable can be found
	if (Utilities::isValidVarName(varName) && indexTable.find(varName) != indexTable.end()){
		return true;
	}else{
		return false;
	}
}

bool VarTable::isVarExistsInVarTable(Type::Index::Var varIndex){
	// valid variable index and variable exists
	if (Utilities::isValidVarIndex(varIndex) && nameTable.find(varIndex) != nameTable.end()){
		return true;
	}else{
		return false;
	}
}